#!/usr/bin/perl

use strict;

use lib qw( lib t/lib );
use SQLiteTest;
use DataValidatorSchemaLoaderMySQL;
use Data::Dumper;
use Scalar::Util qw/ blessed /;


BEGIN {
    if ( $ENV{ MYSQL_USER } && $ENV{ MYSQL_PASSWORD } ) {
        eval 'use Test::More tests => 5;';
    }
    else {
        eval 'use Test::More tests => 1;';
    }
};

my $schema;
my $id = 10;
my $has_modules = 0;
my $has_connection = 0;

if ( $ENV{ MYSQL_USER } ) {
    ok( test_modules(), "Check wheter mysql modules are installed" );
    ok( test_connection(), "Test connection to mysql database" );
    ok( test_create(), "Test create with native validation" );
    ok( test_create_invalid(), "Test create with invalid data" );
    ok( test_cleanup(), "Cleanup created database" );
}
else {
    ok( 1, "No MySQL credentials in ENV (MYSQL_USER, MYSQL_PASSWORD)" );
}

sub test_modules {
    eval {
        eval 'use DBD::mysql;';
    };
    return 0 if $@;
    $has_modules++;
    return 1;
}

sub test_connection {
    return 0 unless $has_modules;
    if ( $ENV{ MYSQL_USER } && $ENV{ MYSQL_PASSWORD } ) {
        $ENV{ MYSQL_HOST } ||= 'localhost';
        $ENV{ MYSQL_DATABASE } ||= 'validation_test';
        
        # connection info ..
        my @connection = (
            "dbi:mysql:host=$ENV{ MYSQL_HOST }",
            $ENV{ MYSQL_USER },
            $ENV{ MYSQL_PASSWORD },
            { AutoCommit => 1 }
        );
        
        # setup connection
        $schema = 'DataValidatorSchemaLoaderMySQL';
        eval {
            $schema->connection( @connection );
        };
        
        warn "CONNECT ". Dumper [ $@ ] if $@;
        
        return 0 if $@;
        
        # init table
        my $sql_file = 't/var/mysql_test.sql';
        open my $sql_fh, "<", $sql_file or die "Cannot open '$sql_file' for read";
        my $sql_code;
        {
            local $/ = undef;
            $sql_code = <$sql_fh>;
        }
        close $sql_fh or die "Cannot close '$sql_file' after read";
        
        eval {
            $schema->storage->dbh->do( sprintf( 'CREATE DATABASE IF NOT EXISTS `%s`', $ENV{ MYSQL_DATABASE } ) );
            $schema->storage->dbh->do( sprintf( 'USE `%s`', $ENV{ MYSQL_DATABASE } ) );
            $schema->storage->dbh->do( $_ )
                for split( /;\n+/, $sql_code );
        };
        
        warn Dumper [ $@ ] if $@;
        return 0 if $@;
        
        $schema->rescan();
        
        $has_connection++;
        return 1;
    }
    return 1;
}

sub test_create {
    return 0 unless $has_connection;
    eval {
        my $test = $schema->resultset( 'TestTable' )->create( {
            an_integer  => 1,
            a_float     => 0.32323,
            a_varchar   => 'hello',
            a_date      => "2010-02-27",
            a_datetime  => "2010-02-27 12:00:10",
            a_time      => '12:00:10',
            an_enum     => 'val1',
            a_set       => 'this,is,a,set',
        } );
    };
    return 1 unless $@;
}

sub test_create_invalid {
    return 0 unless $has_connection;
    my $create_data_ref = {
        an_integer  => 'a',
        a_float     => 'x',
        a_varchar   => 'hello this is far to long!',
        a_date      => "not a date",
        a_datetime  => "not a date time",
        a_time      => 'not a time',
        an_enum     => 'wrong_val',
        a_set       => 'oops,wrong,values',
    };
    eval {
        my $test = $schema->resultset( 'TestTable' )->create( $create_data_ref );
    };
    if ( $@ && blessed( $@ ) && $@->isa( 'DBIx::Class::DataValidator::CreateException' ) ) {
        delete $create_data_ref->{ $_ } for $@->invalid_and_missing;
        return scalar keys %{ $create_data_ref } == 0;
    }
    return 0;
}

sub test_cleanup {
    return 0 unless $has_connection;
    eval {
        $schema->storage->dbh->do( 'DROP DATABASE validation_test' );
    };
    return 0 if $@;
    return 1;
}

1;
